﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using UCNKompetenceBors.Model;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Smo.Agent;
using Microsoft.SqlServer.Management.Common;
using UCNKompetenceBors.Database;
using System.Net.Mail;
using System.Net;

namespace UCNKompetenceBors.Admin
{
    public partial class adminResetUsers : System.Web.UI.Page
    {
        ResetUsers _resetUsers;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                BindSubMenu();
                btnAdminResetUsersConfirm.Enabled = false;

                _resetUsers = dbAdmin.GetResetUsers();
                
                if (!_resetUsers.ResetUsersIsStarted)
                {
                    btnAdminResetUsersStart.Visible = true;
                    btnAdminResetUsersConfirm.Visible = false;
                }
                else
                {
                    btnAdminResetUsersStart.Visible = false;
                    btnAdminResetUsersConfirm.Visible = true;

                    if (DateTime.Now > _resetUsers.EndDate)
                        btnAdminResetUsersConfirm.Enabled = true;
                }

                #region Globalization
                string culture = String.Empty;

                if (HttpContext.Current.Session["MyCulture"] != null)
                    culture = HttpContext.Current.Session["MyCulture"].ToString();

                if (!String.IsNullOrEmpty(culture))
                    GeneralTools.SetCulture(culture);

                LocalizeControls();
                #endregion
            }
        }

        /// <summary>
        /// Binds the sub menu links.
        /// </summary>
        private void BindSubMenu()
        {
            hyLinkAdminDashboard.NavigateUrl = "~/Admin/admin.aspx";
            hyLinkUserHandling.NavigateUrl = "~/Admin/adminUsers.aspx";
            hyLinkAdminExchange.NavigateUrl = "~/Admin/adminExchange.aspx";
            hyLinkNewsHandling.NavigateUrl = "~/Admin/adminNews.aspx";
            hyLinkEditInformation.NavigateUrl = "~/Admin/adminInformation.aspx";
            hyLinkContactPerson.NavigateUrl = "~/Admin/adminContactPerson.aspx";
            hylinkDepartment.NavigateUrl = "~/Admin/adminDepartment.aspx";
            hyLinkResetUsers.NavigateUrl = "~/Admin/adminUsersReset.aspx";
        }

        /// <summary>
        /// Marks users for deletion. 
        /// </summary>
        private void MarkUsersForDeletion()
        {
            dbAdmin.MarkUsersForDeletion();
        }

        /// <summary>
        /// Generates a reactivation link, based on the userId.
        /// </summary>
        /// <param name="userID">Specifies the ID of the user to be used.</param>
        /// <returns>A string containing the resulting reactivation link.</returns>
        private string GenerateReactivationLink(Guid userID)
        {
            string result = String.Empty;

            result += "http://localhost:12947/Login/activateUser.aspx";

            result += "?uid=" + userID.ToString();

            result += "&p=undelete";

            return result;
        }

        /// <summary>
        /// Gets a list of all users.
        /// </summary>
        /// <returns>Returns a list of LoginUser objects.</returns>
        private List<LoginUser> GetAllUsers()
        {
            return dbAdmin.GetAllUsers();
        }

        /// <summary>
        /// Send the reactivation link.
        /// </summary>
        private void SendReactivationLink(DateTime endDate)
        {
            List<LoginUser> users = GetAllUsers();

            SmtpClient smtpClient = new SmtpClient();
            smtpClient.Host = "InsertSmtpHostHere"; //Example smtp.gmail.com or something@ucnkompetencebors.dk
            smtpClient.Port = 0; //Insert network port to the host here example is 587 for gmail
            smtpClient.Credentials = new NetworkCredential("EmailUserName", "EmailPassword"); //Insert credentials for the smtp server here
            smtpClient.EnableSsl = true;

            if (users.Count > 0)
            {
                foreach (LoginUser user in users)
                {
                    string link = GenerateReactivationLink(user.UserID);

                    StringBuilder sbEmailBody = new StringBuilder();
                    sbEmailBody.Append("Kære " + user.UserName + "<br /><br />");
                    sbEmailBody.Append("Vi har nu startet vores halvårlige oprydning af brugere, grundet dette er din konto blevet markeret til sletning og vil blive slettet om en måneds tid efter d. " + endDate.ToString("d. MMMM yyyy") + ". Hvis du fortsat ønsker at bruge UCN Kompetence Børs, kan du følge de instrukser du kan finde herunder.");
                    sbEmailBody.Append("<br /><br />");
                    sbEmailBody.Append("Tryk på det følgende link, for at markere at du ønsker at beholde din konto.");
                    sbEmailBody.Append("<br />");
                    sbEmailBody.Append(link);
                    sbEmailBody.Append("<br /><br />");

                    sbEmailBody.Append("Dear " + user.UserName + "<br /><br />");
                    sbEmailBody.Append("We have just started our biannual user account cleanup, as such your account has been marked for deletion and will be deleted in about a month after the " + endDate.ToString("d. MMMM yyyy") + ". If you wish to keep using the UCN Competence Exchange, you can follow the instructions below.");
                    sbEmailBody.Append("<br /><br />");
                    sbEmailBody.Append("Please click on the following link to mark that you wish to keep your account.");
                    sbEmailBody.Append("<br />");
                    sbEmailBody.Append(link);
                    sbEmailBody.Append("<br /><br />");
                    sbEmailBody.Append("UCN Kompetence Børs / UCN Competence Exchange");

                    //Insert the e-mail from which the message should be sent instead of "FromEmail"
                    MailMessage msg = new MailMessage("FromEmail", user.Email);
                    msg.Body = sbEmailBody.ToString();
                    msg.IsBodyHtml = true;
                    msg.Subject = "Bruger oprydning / User account cleanup";

                    smtpClient.Send(msg);
                }
            }
        }

        /// <summary>
        /// Generates and posts a news post, notifying the starting of the reset process and explaining what it is about.
        /// </summary>
        /// <param name="endDate">Specifies the end date of the reset process, to be used in the news post.</param>
        private void GenerateNewsPost(DateTime endDate)
        {
            _resetUsers = dbAdmin.GetResetUsers();

            string title = _resetUsers.NewsTitle;
            string text = _resetUsers.NewsText.Replace("@DATO", endDate.ToString("d of MMMM yyyy"));
            string locTitle = _resetUsers.NewsLocalizedTitle;
            string locText = _resetUsers.NewsLocalizedText.Replace("@DATO", endDate.Day.ToString() + GetDaySuffix(endDate.Day) + " of " + endDate.ToString("MMMM yyyy"));

            dbAdmin.CreateNews(title, text, false, "", "en-GB", locTitle, locText);
        }

        /// <summary>
        /// Returns the suffix necessary, based on the day input parameter (example suffixes: rd, th, nd).
        /// </summary>
        /// <param name="day">Specifies the day to determine the suffix for.</param>
        /// <returns>Returns a string specifying the suffix.</returns>
        private string GetDaySuffix(int day)
        {
            switch (day)
            {
                case 1:
                case 21:
                case 31:
                    return "st";
                case 2:
                case 22:
                    return "nd";
                case 3:
                case 23:
                    return "rd";
                default:
                    return "th";
            }
        }

        /// <summary>
        /// Starts the reset users process, based on the input parameters.
        /// </summary>
        /// <param name="startDate">Specifies the start date to be used.</param>
        /// <param name="endDate">Specifies the end date to be used.</param>
        public static void StartResetUsers(DateTime startDate, DateTime endDate)
        {
            dbAdmin.StartResetUsers(startDate, endDate);
        }

        /// <summary>
        /// Creates an SQL job to delete users marked for deletion.
        /// </summary>
        /// <param name="startDate">Specifies the starting date of the SQL job.</param>
        //private void CreateDeletionJob(DateTime startDate)
        //{
        //    dbAdmin.CreateDeletionJob(startDate);
        //}

        protected void btnAdminResetUsersStart_Click(object sender, EventArgs e)
        {
            DateTime startDate = DateTime.Now;
            DateTime endDate = DateTime.Now.AddDays(30);

            //Marks all users for deletion in the database
            MarkUsersForDeletion();

            //Starts the reset users process with the current date as startDate and the current date + 30 days as endDate
            StartResetUsers(startDate, endDate);

            //Autogenerates a news post explaining what is going to happen, to let users know in case they miss the e-mail sent to them.
            GenerateNewsPost(endDate);

            //Sends the reactivation links to all users
            //SendReactivationLink(endDate);
        }

        //Event fired when the confirmation button is clicked
        protected void btnAdminResetUsersConfirm_Click(object sender, EventArgs e)
        {
            //Deletes all users still marked for deletion
            dbAdmin.DeleteUsersMarkedForDeletion();
        }

        /// <summary>
        /// Localizes the controls of the site, based on the current UI Culture.
        /// </summary>
        private void LocalizeControls()
        {
            hyLinkAdminDashboard.Text = GetLocalResourceObject("hyLinkAdminDashboardText").ToString();
            hyLinkUserHandling.Text = GetLocalResourceObject("hyLinkUserHandlingText").ToString();
            hyLinkAdminExchange.Text = GetLocalResourceObject("hyLinkAdminExchangeText").ToString();
            hyLinkNewsHandling.Text = GetLocalResourceObject("hyLinkNewsHandlingText").ToString();
            hyLinkEditInformation.Text = GetLocalResourceObject("hyLinkEditInformationText").ToString();
            hyLinkResetUsers.Text = GetLocalResourceObject("hyLinkResetUsersText").ToString();
            hyLinkContactPerson.Text = GetLocalResourceObject("hyLinkContactPersonText").ToString();
            hyLinkContactPerson.Text = GetLocalResourceObject("hyLinkContactPersonText").ToString();
            hylinkDepartment.Text = GetLocalResourceObject("hylinkDepartmentText").ToString();

            lblAdminResetUsersHeader.Text = GetLocalResourceObject("lblAdminResetUsersHeaderText").ToString();
            lblResetUsersConfirm.Text = GetLocalResourceObject("lblResetUsersConfirmText").ToString();

            btnAdminResetUsersStart.Text = GetLocalResourceObject("btnAdminResetUsersText").ToString();
        }
    }
}